<script setup lang="ts">
import { TresCanvas, useRenderLoop, useLoader } from "@tresjs/core";
import { OrbitControls, GLTFModel, useGLTF, Line2 } from "@tresjs/cientos";
import gsap from "gsap";
import {
  BasicShadowMap,
  SRGBColorSpace,
  NoToneMapping,
  TextureLoader,
} from "three";

const ComLine = defineAsyncComponent(() => import("/@/components/ComLine.vue"));

const { onLoop } = useRenderLoop();

const gl = {
  clearColor: "#101010",
  shadows: true,
  alpha: false,
  shadowMapType: BasicShadowMap,
  outputColorSpace: SRGBColorSpace,
  toneMapping: NoToneMapping,
};

// 原始位置
const elWhiteBox = shallowRef();
const whiteBox = reactive({
  position: [2, 0, 10],
  open: () => {
    if (elPoleBox.value) {
      gsap.to(elPoleBox.value, {
        rotationY: 45,
      });
    }
    aniFun();
  },
});

const elPssiveBox = shallowRef();
const passiveBox = reactive({
  position: [0, 0, 5],
});

const lineBox = reactive({
  points: [
    [2, -0.8, 10],
    [0, -0.8, 5],
    [-9, -0.8, -18],
  ],
  color: "#fff",
});

const elPoleBox = shallowRef();
const billar = reactive({
  billarPosition: [0, 0.15, 0],
  billarUrl:
    "https://cdn.sunsagri.com/group1/default/20240808/16/29/0/billar.gltf",
  polePosition: [-2, 6, 25],
  poleUrl:
    "https://cdn.sunsagri.com/group1/default/20240808/17/08/0/billar-pole.gltf",
});

const aniFun = () => {
  const tl = gsap.timeline({ repeat: -1 });
  // 球杆
  tl.to(elPoleBox.value.position, {
    z: 23,
    ease: "wiggle",
    duration: 3,
  });
  // 白球
  tl.to(
    elWhiteBox.value.position,
    {
      z: 5,
      x: 0,
      ease: "expo.out",
      duration: 5,
    },
    ">-2"
  );
  tl.to(
    elPssiveBox.value.position,
    {
      z: -17,
      x: -8.5,
      ease: "power2.out",
      duration: 5,
    },
    ">-4"
  );
  tl.to(
    elPssiveBox.value.position,
    {
      z: -19,
      x: -10,
      ease: "power2.out",
    },
    ">"
  );
  tl.to(
    elPssiveBox.value.position,
    {
      y: -5,
      ease: "power2.out",
    },
    ">"
  );
  tl.play();
};

onLoop(({ delta, elapsed }: any) => {
  if (elWhiteBox.value) {
    const { x, y, z } = elWhiteBox.value.position;
    const [sx, sy, sz] = whiteBox.position;
    if (x !== sx || y !== sy || z !== sz) {
      elWhiteBox.value.rotation.y += delta;
      elWhiteBox.value.rotation.z = elapsed * 10;
      elWhiteBox.value.rotation.x += delta;
    }
  }
  if (elPssiveBox.value) {
    const { x, y, z } = elPssiveBox.value.position;
    const [sx, sy, sz] = passiveBox.position;
    if (x !== sx || y !== sy || z !== sz) {
      elPssiveBox.value.rotation.y += delta;
      elPssiveBox.value.rotation.z = elapsed * 10;
      elPssiveBox.value.rotation.x += delta;
    }
  }
});

let texture = ref<any>({
  isShow: false,
});
const billarPoleModel = shallowRef();
const getMaterial = async () => {
  texture.value = await useLoader(
    TextureLoader,
    "https://cdn.sunsagri.com/group1/default/20240808/10/45/0/box14.jpeg"
  );
  const { scene: model } = await useGLTF(
    "https://cdn.sunsagri.com/group1/default/20240808/17/08/0/billar-pole.gltf"
  );
  model.rotation.x = 75;
  billarPoleModel.value = model;
  if (texture.value.uuid && model.uuid) texture.value.isShow = true;
};
getMaterial();
</script>

<template>
  <div class="page-all" v-if="texture.isShow">
    <TresCanvas v-bind="gl" shadows window-size alpha>
      <TresPerspectiveCamera
        :position="[5, 20, 8]"
        :args="[80, 80, 1, 10000]"
        visible
      />
      <OrbitControls :maxPolarAngle="1.5" />
      <!-- 灯光 -->
      <TresDirectionalLight :position="[0, 2, 4]" :intensity="2" cast-shadow />
      <!-- 移动  X Z Y-->
      <!-- 白球 -->
      <TresMesh
        :position="whiteBox.position"
        ref="elWhiteBox"
        @click="whiteBox.open"
      >
        <TresSphereGeometry />
        <TresMeshToonMaterial color="#f2f2f2" />
      </TresMesh>
      <!-- 红球 -->
      <TresMesh :scale="1" :position="passiveBox.position" ref="elPssiveBox">
        <TresSphereGeometry />
        <TresMeshStandardMaterial :map="texture" />
      </TresMesh>

      <!-- 球杆 -->
      <!-- <Suspense>
        <GLTFModel
          :scale="3"
          ref="elPoleBox"
          :position="billar.polePosition"
          :path="billar.poleUrl"
        />
      </Suspense> -->
      <Suspense>
        <primitive
          :object="billarPoleModel"
          :scale="3.5"
          ref="elPoleBox"
          :position="billar.polePosition"
          @click="whiteBox.open"
        />
      </Suspense>
      <!-- 球桌 -->
      <Suspense>
        <GLTFModel
          :scale="0.5"
          :position="billar.billarPosition"
          :path="billar.billarUrl"
        />
      </Suspense>
      <!-- 线 -->
      <ComLine
        :points="lineBox.points"
        :lineWidth="10"
        :color="lineBox.color"
        :alphaToCoverage="true"
        :opacity="0.3"
      />
      <!-- <Line2  /> -->
    </TresCanvas>
  </div>
</template>

<style>
html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  width: 100%;
}
#app {
  height: 100%;
  width: 100%;
}
</style>
